package com.logistic.server.common.handler;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.logistic.server.common.annotation.LoginRequired;
import com.logistic.server.common.constant.Constants;
import com.logistic.server.common.constant.RedisConst;
import com.logistic.server.common.exception.UnauthorizedException;
import com.logistic.server.common.utils.CookieUtil;
import com.logistic.server.common.utils.RedisUtils;
import com.logistic.server.entity.common.WebUserToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 拦截器
 * @author swen
 */
@Slf4j
@Component
public class AuthorizationInterceptor implements HandlerInterceptor {

    @Resource
    private RedisUtils redisUtils;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws RuntimeException {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        // 获取方法上的注解
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        LoginRequired loginRequired = method.getAnnotation(LoginRequired.class);
        // 如果方法上的注解为空 则获取类的注解
        if (loginRequired == null) {
            loginRequired = method.getDeclaringClass().getAnnotation(LoginRequired.class);
        }
        // 如果标记了注解，则判断权限
        if (loginRequired != null) {
            //验证头中token的有效性
            String token = CookieUtil.get(request, Constants.TOKEN);
            if (StrUtil.isNotBlank(token)) {
                WebUserToken user = JSONObject.parseObject(redisUtils.get(RedisConst.ACCESS_TOKEN + token), WebUserToken.class);
                if (ObjectUtil.isNotEmpty(user)) {
                    return true;
                }
            }
            log.info("认证已失效，清重新登录！");
            throw new UnauthorizedException("认证已失效，清重新登录！");
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    }
}
